<?php
/**
 * XmuSlh, web platform of Student Association Federation of Xiamen University
 * 
 * Rewritting one or some pages of StatusNet. 
 * To get the original version, please visit <http://status.net/>.
 * 
 * StatusNet, the distributed open-source microblogging tool
 * 
 * LICENCE: This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * The Data class for table 'data'.
 * 
 * @author		ytukie <ytukie@gmail.com>
 * @version		0.1
 */

// XmuSlh only.
if ( !defined('XMUSLH')) { exit(1); }

// Requirements.
require_once INSTALLDIR . '/lib/slh_util.php';
require_once INSTALLDIR . '/lib/slh_cache.php';
require_once INSTALLDIR . '/lib/slh_arraywrapper.php';

require_once INSTALLDIR . '/classes/Memcached_DataObject.php';
require_once INSTALLDIR . '/classes/File.php';

// Definitions.
// Column of status reserves.
define('DATA_ICONTYPE_DOC',		1);			// for doc, docx
define('DATA_ICONTYPE_XLS',		2);			// for xls, xlsx
define('DATA_ICONTYPE_PPT',		3);			// for ppt, pptx
define('DATA_ICONTYPE_ZIP',		4);			// for rar, zip
define('DATA_ICONTYPE_OTHER',	5);			// for others


class Data extends Memcached_DataObject
{
	public $__table = 'data';				// table name
	public $id;								// int(11)  primary_key not_null
	public $status;							// tinyint(4)
	public $file_id;						// int(11)  foreign_key not_null
	public $title;							// varchar(255)
	public $message;						// text
	public $icontype;						// tinyint(4)
	public $downloadcnt;					// int(4)
	public $created;						// datetime()  not_null
	
	// Static get
	function staticGet($key, $value = null)
	{
		return Memcached_DataObject::staticGet('Data', $key, $value); 
	}
	
	/**
	 * Get the relative File object.
	 */
	function getFile()
	{
		return Memcached_DataObject::staticGet('File', 'id', $this->file_id);
	}
	
	/**
	 * Get the file url from the relative File field.
	 */
	function getFileUrl()
	{
		$file = Memcached_DataObject::staticGet('File', 'id', $this->file_id);
		if ($file) {
			return $file->fileurl();
		} else {
			return false;
		}
	}
	
	/**
	 * Increase the download count of the data by 1.
	 */
	function increaseDownloadCount()
	{
		$query = 'UPDATE `data` SET `downloadcnt` = `downloadcnt`+1 ' .
				 'WHERE `file_id` = ' . $this->file_id;
		
		$data = new Data();
		return $data->query($query);
	}
	
	/**
	 * Get the original file name of the file related to this data.
	 */
	function getOriginalname()
	{
		$query = 'SELECT `originalname` FROM `file` WHERE `id` = ' . $this->file_id;
		
		$file = new File();
		$file->query($query);
		
		if ($file->fetch()) {
			return $file->originalname;
		} else {
			return ' ';
		}
	}
	
	/**
	 * Delete the data with its relative file.
	 */
	function delete()
	{
		$file = $this->getFile();
		$file->delete();
		
		parent::delete();
	}
	
	/**
	 * Adds a new data (includes a file) in the table 'data' and 'file;.
	 * 
	 * @return int, the Data id; false, failed.
	 */
	static function add($fields)
	{
		// Magically put fields into current scope.
		extract($fields);
		
		if ( !is_object($file) || !($file instanceof Memcached_DataObject)) {
			return false;
		}
		
		// BEGIN
		$file->query('BEGIN');
		
		$file_id = $file->insert();
		if (empty($file_id)) {
			slh_log_db_error($file, 'INSERT', __FILE__);
			$file->query('ROLLBACK');
			return false;
		}
		
		$data = new Data();
		$data->title = $title;
		$data->message = $message;
		$data->file_id = $file_id;
		
		// Get the icontype..
		$dotpos = mb_strrpos($file->filename, '.');
		if ($dotpos) {
			$ext = mb_substr($file->filename, $dotpos + 1);
			
			switch (strtolower($ext)) {
				case 'doc':
				case 'docx': {
					$data->icontype = DATA_ICONTYPE_DOC;
					break;
				}
				case 'xls':
				case 'xlsx': {
					$data->icontype = DATA_ICONTYPE_XLS;
					break;
				}
				case 'ppt':
				case 'pptx': {
					$data->icontype = DATA_ICONTYPE_PPT;
					break;
				}
				case 'zip':
				case 'rar': {
					$data->icontype = DATA_ICONTYPE_ZIP;
					break;
				}
				default: {
					$data->icontype = DATA_ICONTYPE_OTHER;
				}
			}
		}
		
		$data->created = slh_sql_now();
		
		$data_id = $data->insert();
		if (empty($data_id)) {
			slh_log_db_error($data, 'INSERT', __FILE__);
			return false;
		}
		
		// COMMIT
		$file->query('COMMIT');
		
		return $data_id;
	}
	
	/**
	 * Get the ids as a list. Use offset and limit to control
	 * the pagination.
	 */
	static function getIdsByList($offset = 0,
								 $limit = 0)
	{
		$data = new Data();
		
		$data->selectAdd();
		$data->selectAdd('id');
		
		$data->orderBy('created DESC');
		
		if ( !is_null($offset)) {
			$data->limit($offset, $limit);
		}
		
		$ids = array();
		if ($data->find()) {
			while ($data->fetch()) {
				$ids[] = $data->id;
			}
		}
		
		$data->free();
		$data = NULL;
		
		return $ids;
	}
	
	/**
	 * Get the special ids of the datas.
	 * 
	 * Usually the list with pagination.
	 */
	static function getDatasByIds($ids)
	{
		$cache = Cache::instance();
		
		if ( !empty($cache)) {
			$datas = array();
			foreach ($ids as $id) {
				$d = Data::staticGet('id', $id);
				if ( !empty($d)) {
					$datas[] = $d;
				}
			}
			
			return new ArrayWrapper($datas);
		} else {
			// Miss the cache.
			$datas = new Data();
			if (empty($ids)) {
				return $datas;
			}
			
			$datas->whereAdd('id in (' . implode(', ', $ids) . ')');
			$datas->find();
			
			$temp = array();
			while ($datas->fetch()) {
				$temp[$datas->id] = clone($datas);
			}
			
			$wrapped = array();
			
			foreach($ids as $id) {
				if (array_key_exists($id, $temp)) {
					$wrapped[] = $temp[$id];
				}
			}
			
			return new ArrayWrapper($wrapped);
		}
	}
	
}
?>